﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using System.IO;
using System.Reflection;
using LitJson;

public class TableDatabase
{
    public int ID;
}

public class ConfigSingleton<Tt, Td> where Tt : new() where Td : TableDatabase, new()
{
    #region 单例
    static Tt _instance;

    static ConfigSingleton()
    {
        _instance = new Tt();
    }

    public static Tt instance
    {
        get
        {
            return _instance;
        }
    }
    #endregion 单例

    #region 读表
    public List<Td> All = new List<Td>();

    public ConfigSingleton()
    {
        load("Config/" + GetType().Name + ".csv");
    }
    protected void load(string path)
    {
        // 读数据
        Stream bytesData;
#if UNITY_EDITOR
        path = Application.dataPath + "/../" + path;
        bytesData = File.OpenRead(path);
#else
        var bytes = ResMgr.instance.LoadConfig(path);
        bytesData = new MemoryStream(bytes);
#endif

        using (var reader = new StreamReader(bytesData))
        {
            var lineStr = reader.ReadLine();// 第一行是文字说明，跳过
            lineStr = reader.ReadLine();
            var ColumnNameList = lineStr.Split(','); // 字段名
            // 反射字段
            List<FieldInfo> fieldList = new List<FieldInfo>();
            foreach (var column in ColumnNameList)
            {
                fieldList.Add(typeof(Td).GetField(column));
            }

            // 数据
            lineStr = reader.ReadLine();
            while (lineStr != null)
            {
                var ColumnList = lineStr.Split(',');
                int index = 0;
                Td item = new Td();
                foreach (var data in ColumnList)
                {
                    // 解析数据并写入
                    parseField(item, data, fieldList[index]);

                    ++index;
                }

                All.Add(item);
                lineStr = reader.ReadLine();
            }
        }
    }

    /// <summary>
    /// 解析字段，支持类型见代码
    /// </summary>
    private void parseField(Td item, string data, FieldInfo field)
    {
        if (field == null) { return; }

        var fieldType = field.FieldType;
        var jsonAttrList = field.GetCustomAttributes(typeof(JsonFieldAttribute), true);
        if (jsonAttrList.Length > 0) // 该字段是json字段
        {
            JsonReader reader = new JsonReader(data);
            field.SetValue(item, JsonMapper.ReadValue(fieldType, reader));
            return;
        }

        // 整型
        if (fieldType == typeof(int))
        {
            field.SetValue(item, int.Parse(data));
        }
        // 字符串
        else if (fieldType == typeof(string))
        {
            checkAndTranslationChar(field, ref data);
            field.SetValue(item, data);
        }
        // 浮点型
        else if (fieldType == typeof(float))
        {
            field.SetValue(item, float.Parse(data));
        }
        // 整型数组
        else if (fieldType == typeof(List<int>))
        {
            var split = data.Split('$');
            List<int> tmpList = new List<int>();
            foreach (var s in split)
            {
                tmpList.Add(int.Parse(s));
            }
            field.SetValue(item, tmpList);
        }
        // 字符串数组
        else if (fieldType == typeof(List<string>))
        {
            checkAndTranslationChar(field, ref data);
            field.SetValue(item, new List<string>(data.Split('$')));
        }
        // 浮点型数组
        else if (fieldType == typeof(List<float>))
        {
            var split = data.Split('$');
            List<float> tmpList = new List<float>();
            foreach (var s in split)
            {
                tmpList.Add(float.Parse(s));
            }
            field.SetValue(item, tmpList);
        }
        // 枚举类型
        else if (fieldType.IsEnum)
        {
            field.SetValue(item, int.Parse(data));
        }
        // 同一个Dll中的类
        else if (fieldType == typeof(Type))
        {
            Type type = Type.GetType(data);
            //object obj = type.Assembly.CreateInstance(data);
            field.SetValue(item, type);
        }
    }

    /// <summary>
    /// 检查并转译字符串
    /// </summary>
    void checkAndTranslationChar(MemberInfo field, ref string str)
    {
        if (field.IsDefined(typeof(TranslationFieldAttribute), false))
        {
            str = str.Replace("[1]", ",");
        }
    }
#endregion 读表

    /// <summary>
    /// 按ID索引
    /// </summary>
    /// <returns></returns>
    public Td this[int ID]
    {
        get { return All.FirstOrDefault(tableObj => tableObj.ID == ID); }
    }
}
